#include "Database.h"

Database::Database(const string &n)
{
	name = n;
	
	//search for table names
	string search_name = "./"+name + "_*.dat";

	vector<string> ret;

	WIN32_FIND_DATA f;
	HANDLE h = FindFirstFile(search_name.c_str(), &f);
	if(h != INVALID_HANDLE_VALUE)
	{
		do
		{
			ret.push_back(tname_from_fname(f.cFileName));
		} while(FindNextFile(h, &f));
	}
	else
	{
		//fprintf(stderr, "Error opening directory\n");
	}

	string temp;
	for(vector<string>::iterator it = ret.begin(); it != ret.end(); ++it) {
		temp = name + "_" + *it + ".dat";
		if(PathFileExists(temp.c_str()))
		{
			table.push_back(new Table(*it, name));
		}
	}
}


Database::~Database(void)
{
	for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
	{
		delete *it;
	}
}

string Database::get_name() const
{
	return name;
}

vector<string> Database::list_tables()
{
	vector<string> ret;

	for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
	{
		ret.push_back((*it)->get_name());
	}

	return ret;
}

Table* Database::load_table(const bool& newtable)
{
	Table* ret = 0;

	if(newtable)
	{
		string tn = "";
		do
		{
			if(tn != "")
			{
				cout << "Table already exists. Type another name." << endl;
			}
			tn = Validator::get<string>();
		} while(table_exists(tn));

		ret = new Table(tn, name);
		table.push_back(ret);
	}
	else
	{
		int sel = 0;
		int tsize = static_cast<int>(table.size());

		cout << "Choose a table from the list" << endl;
		do
		{
			int i = 0;
			for(i=0; i<tsize; ++i)
			{
				cout << (i+1) << ". " << (table[i])->get_name() << endl;
			}
			cout << i+1 << ". back" << endl;
			sel = Validator::get<int>("Select an option: ");
		} while(sel <= 0 || sel > tsize+1);

		if(sel < tsize+1)
		{
			ret = table[sel-1];
		}
	}


	return ret;
}

bool Database::table_exists(const string& t_name)
{
	bool ret = false;
	for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
	{
		ret = t_name == (*it)->get_name();
	}
	return ret;
}

void Database::save()
{
	for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
	{
		(*it)->save();
	}
}

void Database::truncate()
{
	for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
	{
		(*it)->del(false);
	}
}

void Database::drop(const bool& all)
{
	if(all)
	{
		for(vector<Table*>::iterator it = table.begin(); it != table.end(); ++it)
		{
			(*it)->drop();
			delete *it;
		}
		table.clear();
	}
	else
	{
		int sel = 0;
		int tsize = static_cast<int>(table.size());

		cout << "Choose a table from the list" << endl;
		do
		{
			int i = 0;
			for(i=0; i<tsize; ++i)
			{
				cout << (i+1) << ". " << (table[i])->get_name() << endl;
			}
			cout << i+1 << ". back" << endl;
			sel = Validator::get<int>("Select an option: ");
		} while(sel <= 0 || sel > tsize+1);

		if(sel < tsize+1)
		{
			(table[sel-1])->drop();
			delete table[sel-1];
			table.erase(table.begin() + (sel - 1));
		}
	}
}

bool Database::empty() const
{
	return table.size() == 0;
}



string Database::tname_from_fname(const string &a) const
{
	int xpos = a.find('_');
	int ypos = a.find('.');
	string ret = "";
	if(xpos!=string::npos && ypos!=string::npos)
	{
		ret = a.substr(xpos+1, ypos-xpos-1);
	}
	return ret;
}
